package com.superquan.selfstudybootmybatis.utils.common;

import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @author zwq
 * @description 数据处理通用类：将各种日期进行自定义格式化，各种对象转换成string，保留自定义位小数点等功能
 * @date 2022/4/25
 */
public class DataHelper {
    @SuppressWarnings("unused")
    private static DecimalFormat df = new DecimalFormat("0.00000000000000");

    /**
     * 将任何对象转成string
     *
     * @param obj 需要转换的对象
     *
     * @return
     */
    public static String getString(Object obj) {
        return getString(obj, "");
    }

    /**
     * 将任何对象转成string
     *
     * @param obj 需要转换的对象
     * @param defaultValue 如果为空，则使用该值作为输出
     *
     * @return
     */
    public static String getString(Object obj, String defaultValue) {
        if (obj == null)
            return defaultValue;
        if (obj instanceof String) {
            String objStr = (String) obj;
            if (objStr.equals("") || objStr.trim().equals("null"))
                return defaultValue;
            return objStr;
        } else if (obj instanceof Date) {
            Date tDate = (Date) obj;
            return tDate.toString();
        } else if (obj instanceof BigDecimal) {
            BigDecimal _id = (BigDecimal) obj;
            return _id.toString();
        } else if (obj instanceof Integer) {
            return (Integer) obj + "";
        } else if (obj instanceof Long) {
            return (Long) obj + "";
        } else if (obj instanceof Float) {
            Float f = (Float) obj;
            return Float.toString(f.floatValue());
        } else if (obj instanceof Double) {
            Double d = (Double) obj;
            return Double.toString(d.doubleValue());
        } else if (obj instanceof Boolean) {
            Boolean b = (Boolean) obj;
            if (b) {
                return "true";
            } else {
                return "false";
            }
        } else if (obj instanceof Clob) {
            Clob clob = (Clob) obj;
            Reader is = null;
            StringBuffer sb = new StringBuffer();
            BufferedReader br = null;
            try {
                is = clob.getCharacterStream();// 得到流
                br = new BufferedReader(is);
                String s = br.readLine();
                while (s != null) {// 执行循环将字符串全部取出付值给StringBuffer由StringBuffer转成STRING
                    sb.append(s);
                    s = br.readLine();
                }
            } catch (Exception e) {
                e.printStackTrace();
                return defaultValue;
            } finally {
                try {
                    if (br != null) {
                        br.close();
                    }
                    if (is != null) {
                        is.close();
                    }
                } catch (IOException e) {
                }
            }
            return sb.toString();
        } else if (obj instanceof Blob) {
            Blob blob = (Blob) obj;
            String outfile = "";
            BufferedInputStream bi = null;
            try {
                bi = new BufferedInputStream(blob.getBinaryStream());
            } catch (SQLException e) {
                e.printStackTrace();
            }
            if (bi != null) {
                byte[] data = new byte[1024];
                try {
                    int len = -1;
                    while ((len = bi.read(data)) != -1) {
                        outfile += new String(data, "UTF-8");
                        data = new byte[len];
                    }
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        bi.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return outfile;
        }
        return defaultValue;
    }

    public static boolean getBoolean(Object obj) {
        if (obj != null && obj instanceof String) {
            String s = (String) obj;
            if ("true".equals(s)) {
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    /**
     * 将Double,Float,Integer对象保留小数点后指定几位小数
     *
     * @param obj 需要转换的对象
     * @param number 需要转换的位数
     * @param 为空则返回 "0"
     */
    public static String numberFormat(Object obj, int number) {
        return numberFormat(obj, number, "0");
    }

    /**
     * 将Double,Float,Integer对象保留小数点后指定几位小数
     *
     * @param obj 需要转换的对象
     * @param number 需要转换的位数
     * @param defaultValue 如果为空，则使用该值作为输出
     */
    public static String numberFormat(Object obj, int number,
                                      String defaultValue) {
        if (obj == null)
            return defaultValue;
        if (obj instanceof Double) {
            Double d = (Double) obj;
            if (!d.equals(Double.NaN)) {
                BigDecimal bd = new BigDecimal(d);
                BigDecimal bd1 = bd.setScale(number, BigDecimal.ROUND_HALF_UP);
                return bd1.toString();
            }
            return defaultValue;
        } else if (obj instanceof Float) {
            Float f = (Float) obj;
            if (!f.equals(Float.NaN)) {
                BigDecimal bd = new BigDecimal(f);
                BigDecimal bd1 = bd.setScale(number, BigDecimal.ROUND_HALF_UP);
                return bd1.toString();
            }
            return defaultValue;
        } else if (obj instanceof Integer) {
            Integer f = (Integer) obj;
            BigDecimal bd = new BigDecimal(f);
            BigDecimal bd1 = bd.setScale(number, BigDecimal.ROUND_HALF_UP);
            return bd1.toString();
        } else if (obj instanceof String) {
            String f = (String) obj;
            BigDecimal bd = new BigDecimal(f);
            BigDecimal bd1 = bd.setScale(number, BigDecimal.ROUND_HALF_UP);
            return bd1.toString();
        } else if (obj instanceof BigDecimal) {
            BigDecimal bd = (BigDecimal) obj;
            BigDecimal result = bd.setScale(number, BigDecimal.ROUND_HALF_UP);
            return result.toString();
        }
        return defaultValue;
    }

    /**
     * 截取字符串
     *
     * @param str 需要截取的字符串
     * @param length 截取的位数
     *
     * @return
     */
    public static String subString(String str, int length) {
        if (str != null) {
            if (str.length() > length) {
                str = str.substring(0, length - 3) + "...";
            }
        } else {
            str = "";
        }
        return str;
    }

    /**
     * 将数字转成固定的位数，前面补0
     *
     * @param number 需要转换的数字
     * @param numberLength 需要转换的位数
     *
     * @return
     */
    public static String getStringByNumber(String number, int numberLength) {
        if (number == null || numberLength < 0)
            return null;
        String numberStr = getString(number);
        String newNumber = numberStr;
        if (numberStr.length() < numberLength) {
            for (int i = 0; i < numberLength - numberStr.length(); i++) {
                newNumber = "0" + newNumber;
            }
            if (numberStr.length() == numberLength)
                return numberStr;
        }
        return newNumber;
    }

    /**
     * 将Date,Calendar,Timestamp 对象转成string
     *
     * @param obj
     * @param format 格式自定，需要有yyyy，MM，dd，hh，mm，ss任意一个
     *
     * @return
     */
    public static String getDateText(Object obj, String format) {
        if (obj == null)
            return "";
        Calendar vCalendar = new GregorianCalendar();
        String wd = "";
        vCalendar = setCalendar(obj);
        String year = vCalendar.get(Calendar.YEAR) + "";
        String month = getStringByNumber((vCalendar.get(Calendar.MONTH) + 1)
                + "", 2);
        String day = getStringByNumber(vCalendar.get(Calendar.DAY_OF_MONTH)
                + "", 2);
        String hour = getStringByNumber(vCalendar.get(Calendar.HOUR_OF_DAY)
                + "", 2);
        String minute = getStringByNumber(vCalendar.get(Calendar.MINUTE) + "",
                2);
        String second = getStringByNumber(
                (vCalendar.get(Calendar.SECOND)) + "", 2);
        int e = (vCalendar.get(Calendar.DAY_OF_WEEK) - 1);
        second = getStringByNumber(second, 2);
        if (format == null) {
            wd = year + "-" + month + "-" + day;
            return wd;
        }
        String week = replaceWeekChinese(e);
        format = replaceFormatStr(format, year, month, day, hour, minute,
                second, week, e);
        return format;
    }

    private static String replaceFormatStr(String format, String year,
                                           String month, String day, String hour, String minute,
                                           String second, String week, int e) {
        format = format.replaceAll("yyyy", year);
        format = format.replaceAll("MM", month);
        format = format.replaceAll("dd", day);
        format = format.replaceAll("hh", hour);
        format = format.replaceAll("mm", minute);
        format = format.replaceAll("ss", second);
        format = format.replaceAll("E", week);
        format = format.replaceAll("e", DataHelper.getString(e));
        return format;
    }

    private static String replaceWeekChinese(int e) {
        String week = "";
        switch (e) {
            case 1:
                week = "\u4e00"; // 一
                break;
            case 2:
                week = "\u4e8c"; // 二
                break;
            case 3:
                week = "\u4e09"; // 三
                break;
            case 4:
                week = "\u56db"; // 四
                break;
            case 5:
                week = "\u4e94"; // 五
                break;
            case 6:
                week = "\u516d"; // 六
                break;
            case 0:
                week = "\u65e5"; // 日
                break;
        }
        return week;
    }

    private static Calendar setCalendar(Object obj) {
        Calendar vCalendar = Calendar.getInstance();
        if (obj instanceof Date) {
            vCalendar.setTime((Date) obj);
        } else if (obj instanceof Calendar) {
            vCalendar = (Calendar) obj;
        } else if (obj instanceof Timestamp) {
            Timestamp t = (Timestamp) obj;
            vCalendar.setTimeInMillis(t.getTime());
        }
        return vCalendar;
    }

    /**
     * 将Date,Calendar,Timestamp 对象转成string
     *
     * @param obj
     * @param format 格式自定，需要有yyyy，MM，dd，hh，mm，ss任意一个
     *
     * @return
     */
    public static String getPrevMonthDateText(Object obj, String format) {
        if (obj == null)
            return "";
        Calendar vCalendar = new GregorianCalendar();
        String wd = "";
        vCalendar = setCalendar(obj);
        String year = vCalendar.get(Calendar.YEAR) + "";
        String month = getStringByNumber((vCalendar.get(Calendar.MONTH) + 1)
                + "", 2);
        String day = getStringByNumber(vCalendar.get(Calendar.DAY_OF_MONTH)
                + "", 2);
        String hour = getStringByNumber(vCalendar.get(Calendar.HOUR_OF_DAY)
                + "", 2);
        String minute = getStringByNumber(vCalendar.get(Calendar.MINUTE) + "",
                2);
        String second = getStringByNumber(
                (vCalendar.get(Calendar.SECOND)) + "", 2);
        int e = (vCalendar.get(Calendar.DAY_OF_WEEK) - 1);
        if (format == null) {
            wd = year + "-" + month + "-" + day;
            return wd;
        }
        String week = replaceWeekChinese(e);
        format = replaceFormatStr(format, year, month, day, hour, minute,
                second, week, e);
        return format;
    }

    public static Calendar getCalendar(String value, int h, int m, int s) {
        if (value == null)
            return null;
        String[] values = value.split("-");
        if (values == null)
            return null;
        if (values.length != 3)
            return null;
        int year = Integer.parseInt(values[0]);
        int month = Integer.parseInt(values[1]);
        int day = Integer.parseInt(values[2]);
        return setDate(year, month, day, 0, 0, 0);
    }

    public static Calendar getCalendar(String date) {
        if (date == null)
            return null;
        String dd = date.split(" ")[0];
        String hh = date.split(" ")[1];
        String[] values = dd.split("-");
        String[] hhs = hh.split(":");
        if (values == null)
            return null;
        if (values.length != 3)
            return null;
        int year = Integer.parseInt(values[0]);
        int month = Integer.parseInt(values[1]);
        int day = Integer.parseInt(values[2]);

        int hour = 0;
        int mm = 0;
        int ss = 0;
        if (hhs.length > 0 && hhs.length < 1) {
            hour = Integer.parseInt(hhs[0]);
        } else if (hhs.length == 2) {
            hour = Integer.parseInt(hhs[0]);
            mm = Integer.parseInt(hhs[1]);
        } else if (hhs.length == 3) {
            hour = Integer.parseInt(hhs[0]);
            mm = Integer.parseInt(hhs[1]);
            ss = Integer.parseInt(hhs[2]);
        }

        return setDate(year, month, day, mm, hour, ss);
    }

    public static Calendar getCalendar(String date, String time) {
        if (date == null)
            return null;
        String[] values = date.split("-");
        if (values == null)
            return null;
        if (values.length != 3)
            return null;
        int year = Integer.parseInt(values[0]);
        int month = Integer.parseInt(values[1]);
        int day = Integer.parseInt(values[2]);
        if (time != null) {
            String[] times = time.split(":");
            if (times == null)
                return null;
            if (times.length != 3)
                return null;
            int minute = Integer.parseInt(times[1]);
            int hour = Integer.parseInt(times[0]);
            int second = Integer.parseInt(times[2]);
            return setDate(year, month, day, minute, hour, second);
        } else {
            return setDate(year, month, day, 0, 0, 0);
        }
    }

    public static Date getDate(String date, String time) {
        return getCalendar(date, time).getTime();
    }

    private static Calendar setDate(int year, int month, int day, int minute,
                                    int hour, int second) {
        Calendar result = new GregorianCalendar();
        result.set(Calendar.MONTH, month - 1);
        result.set(Calendar.YEAR, year);
        result.set(Calendar.DAY_OF_MONTH, day);
        result.set(Calendar.HOUR_OF_DAY, hour);
        result.set(Calendar.MINUTE, minute);
        result.set(Calendar.SECOND, second);
        return result;
    }

    @SuppressWarnings("unchecked")
    public static BigDecimal toCountNumberList(List<Map<String, Object>> list) {
        BigDecimal countNumber = BigDecimal.ZERO;
        if (!list.isEmpty()) {
            Iterator<Map<String, Object>> it = list.iterator();
            if (it.hasNext()) {
                Object obj = it.next();
                if (obj != null && obj instanceof Map) {
                    Map<String, Object> objLong = (Map<String, Object>) obj;
                    countNumber = (BigDecimal) objLong.get("count");
                }
            }
        }
        return countNumber;
    }

    /**
     * @param obj 所需要转换的对象
     *
     * @return int
     *
     * @throws NumberFormatException
     * @default -1
     */
    public static int getInt(Object obj) {
        return getInt(obj, -1);
    }

    /**
     * @param obj 所需要转换的对象
     *
     * @return int
     *
     * @throws NumberFormatException
     * @default defaultValue
     */
    public static int getInt(Object obj, int defaultValue) {
        if (obj == null)
            return defaultValue;
        if (obj instanceof String) {
            String objStr = (String) obj;
            try {
                return Integer.parseInt(objStr);
            } catch (NumberFormatException e) {
                return defaultValue;
            }
        } else if (obj instanceof Timestamp) {
            return defaultValue;
        } else if (obj instanceof BigDecimal) {
            BigDecimal _id = (BigDecimal) obj;
            return _id.intValue();
        } else if (obj instanceof Integer) {
            return (Integer) obj;
        } else if (obj instanceof Float) {
            BigDecimal tBigDecimal = new BigDecimal((Float) obj);
            return tBigDecimal.intValue();
        } else if (obj instanceof Double) {
            BigDecimal tBigDecimal = new BigDecimal((Double) obj);
            return tBigDecimal.intValue();
        } else if (obj instanceof Long) {
            BigDecimal tBigDecimal = new BigDecimal((Long) obj);
            return tBigDecimal.intValue();
        }
        return defaultValue;
    }

    /**
     * @param obj 所需要转换的对象
     *
     * @return long
     *
     * @throws NumberFormatException
     * @default -1
     */
    public static long getLong(Object obj) {
        return getLong(obj, -1l);
    }

    /**
     * @param obj 所需要转换的对象
     *
     * @return long
     *
     * @throws NumberFormatException
     * @default defaultValue
     */
    public static long getLong(Object obj, long defaultValue) {
        if (obj == null)
            return defaultValue;
        if (obj instanceof String) {
            String objStr = (String) obj;
            try {
                return Long.parseLong(objStr);
            } catch (NumberFormatException e) {
                return defaultValue;
            }
        } else if (obj instanceof Timestamp) {
            return defaultValue;
        } else if (obj instanceof BigDecimal) {
            BigDecimal _id = (BigDecimal) obj;
            return _id.longValue();
        } else if (obj instanceof Long) {
            return (Long) obj;
        } else if (obj instanceof Integer) {
            BigDecimal tBigDecimal = new BigDecimal((Integer) obj);
            return tBigDecimal.longValue();
        } else if (obj instanceof Float) {
            BigDecimal tBigDecimal = new BigDecimal((Float) obj);
            return tBigDecimal.longValue();
        }
        return defaultValue;
    }

    /**
     * @param obj 所需要转换的对象
     *
     * @return int
     *
     * @throws NumberFormatException
     * @default -1
     */
    public static float getFloat(Object obj) {
        return getFloat(obj, -1f);
    }

    /**
     * @param obj 所需要转换的对象
     *
     * @return int
     *
     * @throws NumberFormatException
     * @default -1
     */
    public static double getDouble(Object obj) {
        return getDouble(obj, -1d);
    }

    /**
     * @param obj 所需要转换的对象
     * @param defaultNumber 默认值
     *
     * @return int
     *
     * @throws NumberFormatException
     * @default defaultNumber
     */
    public static float getFloat(Object obj, float defaultNumber) {
        if (obj == null)
            return defaultNumber;
        if (obj instanceof String) {
            String objStr = (String) obj;
            try {
                return Float.parseFloat(objStr);
            } catch (NumberFormatException e) {
                e.printStackTrace();
                return defaultNumber;
            }
        } else if (obj instanceof Timestamp) {
            return defaultNumber;
        } else if (obj instanceof BigDecimal) {
            BigDecimal _id = (BigDecimal) obj;
            return _id.floatValue();
        } else if (obj instanceof Float) {
            return (Float) obj;
        } else if (obj instanceof Integer) {
            BigDecimal tBigDecimal = new BigDecimal((Integer) obj);
            return tBigDecimal.floatValue();
        } else if (obj instanceof Long) {
            BigDecimal tBigDecimal = new BigDecimal((Long) obj);
            return tBigDecimal.floatValue();
        }
        return defaultNumber;
    }

    /**
     * 增加getDouble方法，用于经纬度查询
     *
     * @param obj
     * @param defaultNumber
     *
     * @return
     */
    public static double getDouble(Object obj, double defaultNumber) {
        if (obj == null)
            return defaultNumber;
        if (obj instanceof String) {
            String objStr = (String) obj;
            if (StringUtils.isEmpty(objStr))
                return defaultNumber;
            try {
                return Double.parseDouble(objStr);
            } catch (NumberFormatException e) {
                e.printStackTrace();
                return defaultNumber;
            }
        } else if (obj instanceof Timestamp) {
            return defaultNumber;
        } else if (obj instanceof BigDecimal) {
            BigDecimal _id = (BigDecimal) obj;
            return _id.doubleValue();
        } else if (obj instanceof Double) {
            Double _id = (Double) obj;
            return _id.doubleValue();
        } else if (obj instanceof Integer) {
            BigDecimal tBigDecimal = new BigDecimal((Integer) obj);
            return tBigDecimal.doubleValue();
        } else if (obj instanceof Long) {
            BigDecimal tBigDecimal = new BigDecimal((Long) obj);
            return tBigDecimal.doubleValue();
        }
        return defaultNumber;
    }

    /**
     * 从String[]转换为Long[]
     *
     * @param args 为String数组
     *
     * @return long[]
     */
    public static long[] StringToLong(String[] args) {
        long[] results = new long[args.length];
        for (int i = 0; i < args.length; i++) {
            if (args[i] != null && !("").equals(args[i])) {
                results[i] = Long.parseLong(args[i]);
            }
        }
        return results;
    }

    /**
     * 从String[]转换为int[]
     *
     * @param args 为String数组
     *
     * @return int[]
     */
    public static int[] StringToInteger(String[] args) {
        int[] results = new int[args.length];
        for (int i = 0; i < args.length; i++) {
            if (args[i] != null && !("").equals(args[i])) {
                results[i] = Integer.parseInt(args[i]);
            }
        }
        return results;
    }

    /**
     * 首字母转成大写
     *
     * @param str 需要转换的字符串
     *
     * @return
     */
    public static String firstLetterToUpper(String str) {
        char[] array = str.toCharArray();
        array[0] -= 32;
        return String.valueOf(array);
    }

    // MM，dd，hh，mm，ss
    public static void main(String[] args) {
        System.out.println(getLong("358142030115891"));
    }

}
